package com.example.demo.config.logconfig.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.example.demo.config.consts.LogConst;
import com.example.demo.config.logconfig.LogBack;
import com.example.demo.zhoushengwen.utils.RequestUtil;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
public class ServiceDigestAspect
{
    private long startTime = 0;
    
    @Autowired
    private HttpServletResponse response;
    
    @Autowired
    private HttpServletRequest request;
    
    @Pointcut("execution(* com.example.demo.service..*.*(..))")
    private void pointCutMethod()
    {
        
    }
    
    @Before(value = "pointCutMethod()")
    public void doBefore(JoinPoint joinPoint)
    {
        long begin = System.currentTimeMillis();
        startTime = begin;
        LogBack.info("CLIENTIP:{}|UUID:{}|position:{}|level:{}|status:{}|method:{}|param:{}|consume:{}",
            RequestUtil.getCliectIp(request),
            response.getHeader(LogConst.LOG_UUID),
            LogConst.LOG_SERVICE,
            LogConst.LOG_STATUS_INFO,
            LogConst.LOG_BEGIN,
            joinPoint.getSignature().toString(),
            Arrays.toString(joinPoint.getArgs()),
            0);
    }
    
    /**
     *返回通知
     *@param operation
     *@param returnValue
     */
    @AfterReturning(value = "pointCutMethod()", returning = "returnValue")
    public void doAfterReturning(JoinPoint joinPoint, Object returnValue)
    {
        long end = System.currentTimeMillis();
        LogBack.info("CLIENTIP:{}|UUID:{}|position:{}|level:{}|status:{}|method:{}|param:{}|consume:{}",
            RequestUtil.getCliectIp(request),
            response.getHeader(LogConst.LOG_UUID),
            LogConst.LOG_SERVICE,
            LogConst.LOG_STATUS_INFO,
            LogConst.LOG_END,
            joinPoint.getSignature().toString(),
            returnValue,
            (end - startTime));
    }
    
    /**
     * 异常通知
     * @param operation
     * @param e
     * @see [类、类#方法、类#成员]
     */
    @AfterThrowing(value = "pointCutMethod()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e)
    {
        //出现异常时，记录异常最早出现的位置，让上层去捕捉处理
        long end = System.currentTimeMillis();
        LogBack.info("CLIENTIP:{}|UUID:{}|position:{}|level:{}|status:{}|method:{}|param:{}|consume:{}|error:{}",
            RequestUtil.getCliectIp(request),
            response.getHeader(LogConst.LOG_UUID),
            LogConst.LOG_SERVICE,
            LogConst.LOG_STATUS_ERROR,
            LogConst.LOG_END,
            joinPoint.getSignature().toString(),
            Arrays.toString(joinPoint.getArgs()),
            (end - startTime),
            e);
    }
}
